import base64
import os
import tempfile

import uuid

from flask import request
from pydub import AudioSegment

from controllers.base_controller import BaseController
from speech_recognition_modules.audio_processor import AudioProcessor
from utils.api_response_utils import create_error_response, create_success_response
from utils.logger_config import get_logger_config


class SpeechRecognitionController(BaseController):
    """语音识别控制器，处理语音识别相关请求"""

    def __init__(self, import_name):
        self.logger = get_logger_config(
            name="speech_recognition_controller"
        ).get_logger()
        super().__init__("语音识别", import_name, url_prefix="")

    def register_routes(self):
        """注册路由"""

        @self.route("/extract_speech_text", methods=["POST"])
        @self.validate_json_request()
        @self.swagger_from("swagger_docs/speech_recognition/extract_speech_text.yml")
        def api_extract_speech_text():
            temp_audio_path = None
            try:
                data: dict = request.parsed_data
                audio_base64: str = data.get("audio_base64")
                language: str = data.get("language", "zh-CN")
                is_segment: bool = data.get("is_segment", False)

                if not audio_base64:
                    return create_error_response(400, "参数audio_base64的值为空")

                try:
                    audio_data = base64.b64decode(audio_base64)
                except Exception as e:
                    return create_error_response(400, f"base64解码失败: {e}")

                # 创建临时文件，不带扩展名
                temp_dir = tempfile.gettempdir()
                pid = os.getpid()
                unique_id = uuid.uuid4()
                temp_audio_path = os.path.join(
                    temp_dir, f"temp_audio_pid{pid}_{unique_id}"
                )
                self.logger.debug(f"创建临时文件: {temp_audio_path}")

                with open(temp_audio_path, "wb") as f:
                    f.write(audio_data)

                # 验证音频文件是否有效
                try:
                    audio = AudioSegment.from_file(temp_audio_path)
                    duration_seconds = len(audio) / 1000
                    self.logger.info(f"成功加载音频文件，长度：{duration_seconds}秒")
                except Exception as e:
                    self.logger.error(f"音频文件格式不正确或损坏: {e}")
                    return create_error_response(400, f"音频文件格式不正确或损坏: {e}")

                # 获取复用的AudioProcessor实例并设置语言
                processor = AudioProcessor(
                    language=language
                )  # AudioProcessor.get_instance()
                if processor.language != language:
                    self.logger.info(
                        f"切换 AudioProcessor 语言从 {processor.language} 到 {language}"
                    )
                    processor.language = language

                # 调用whisper识别
                result_obj = processor.extract_text_with_whisper(
                    file_path=temp_audio_path, is_segment=is_segment
                )

                if not result_obj.success:
                    return create_error_response(
                        422, f"语音识别失败: {result_obj.error}"
                    )

                return create_success_response(
                    "语音文本提取成功",
                    {
                        "text": result_obj.text,
                        "duration_seconds": duration_seconds,
                        "language": language,
                        "segments": [vars(s) for s in result_obj.segments],
                    },
                )

            except Exception as e:
                self.logger.error(f"处理音频时发生未知错误: {e}")
                return create_error_response(500, f"处理音频时发生未知错误: {e}")
            finally:
                if temp_audio_path and os.path.exists(temp_audio_path):
                    try:
                        os.remove(temp_audio_path)
                        self.logger.info(f"已删除临时文件: {temp_audio_path}")
                    except Exception as e:
                        self.logger.error(f"删除临时文件失败: {e}")
